<template>
    <el-card shadow="always">
        <el-row class="margin-bottom-20">
            <el-col :span="4">
                <el-button type="primary" @click="isShowAdd=true">添加新角色</el-button>
            </el-col>
        </el-row>
        <el-table border :data="roles" :max-height="h-180" v-loading="isLoading">
			<!-- element ui 表格扩展的基础承载组件仍然是 el-table-column -->
			<el-table-column type="expand">
				<template v-slot:default="{ row }">
					<div class="box-tip" v-if="row.children.length==0">暂未分配权限</div>
					<div class="box" v-else>
						<div class="tag-box"  v-for="one in row.children" :key="one.id">
							<el-tag type="" closable @close="removeRights(row,one.id)">{{ one.authName }}</el-tag>
							<i class="el-icon-caret-right"></i>
							<div class="box">
								<div class="tag-box" v-for="two in one.children" :key="two.id" >
									<el-tag type="success" closable @close="removeRights(row,two.id)">{{ two.authName }}</el-tag>
									<i class="el-icon-caret-right"></i>
									<div class="tag-box box warp">
										<div class="tip" v-for="three in two.children" :key="three.id">
											<el-tag type="warning" closable @close="removeRights(row,three.id)">{{ three.authName }}</el-tag>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
				</template>
			</el-table-column>
			<!-- element ui 表格扩展的基础承载组件仍然是 el-table-column -->
            <el-table-column label="序号" width="80" type="index" prop="index"></el-table-column>
            <el-table-column label="角色名称" prop="roleName"></el-table-column>
            <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
            <el-table-column label="操作" width="300">
				<template v-slot:default="{ row }">
					<el-button type="primary" icon="el-icon-edit" size="mini" @click="showModifyModel(row.id)">编辑</el-button>
					<el-button type="danger" icon="el-icon-delete" size="mini" @click="deleteRole(row.id)">删除</el-button>
					<el-button type="warning" icon="el-icon-setting" size="mini" @click="showSetingModel(row)">分配权限</el-button>
				</template>
            </el-table-column>
        </el-table>

		<!-- 角色添加 -->
		<el-dialog
			title="添加新角色"
			:visible.sync="isShowAdd"
			width="40%"
		>
			<el-form :model="newRole" :rules="roleRule" ref="addRole" label-width="100px">
				<el-form-item label="角色名称" prop="roleName">
					<el-input v-model="newRole.roleName" placeholder="角色名称"></el-input>
				</el-form-item>
				<el-form-item label="角色描述" prop="roleDesc">
					<el-input v-model="newRole.roleDesc" placeholder="角色描述"></el-input>
				</el-form-item>
			</el-form>
			<template v-slot:footer>
				<span class="dialog-footer">
					<el-button @click="isShowAdd = false">取 消</el-button>
					<el-button type="primary" @click="addRuleCallback">确 定</el-button>
				</span>
			</template>
		</el-dialog>
		<!-- 角色修改 -->
		<el-dialog
			title="角色信息修改"
			:visible.sync="isShowModify"
			width="40%"
		>
			<el-form :model="modifyRole" :rules="roleRule" ref="modifyRoleRef" label-width="100px">
				<el-form-item label="角色名称" prop="roleName">
					<el-input v-model="modifyRole.roleName" placeholder="角色名称"></el-input>
				</el-form-item>
				<el-form-item label="角色描述" prop="roleDesc">
					<el-input v-model="modifyRole.roleDesc" placeholder="角色描述"></el-input>
				</el-form-item>
			</el-form>
			<template v-slot:footer>
				<span class="dialog-footer">
					<el-button @click="isShowModify = false">取 消</el-button>
					<el-button type="primary" @click="modifyRuleCallback">确 定</el-button>
				</span>
			</template>
		</el-dialog>
		<!-- 权限分配 -->
		<el-dialog
			title="角色权限修改"
			:visible.sync="isShowSeting"
			width="80%"
		>
			<el-tree
				ref="settingRoleRef"
				:data="allRights"
				:props="{ label:'authName' }"
				node-key="id"
				show-checkbox
				default-expand-all
			></el-tree>
			<template v-slot:footer>
				<span class="dialog-footer">
					<el-button @click="isShowSeting = false">取 消</el-button>
					<el-button type="primary" @click="settingRoleRights">确 定</el-button>
				</span>
			</template>
		</el-dialog>
    </el-card>
</template>
<script>
import { roleRules } from "../../rules/roleRules.js";
import {
	getAllroles,
	addNewRole,
	removeRole,
	getRole,
	modifyRole,
	settingRoleRights,
	removeRoleRights
} from '@/api/roles.js'
import { getAllRights } from "@/api/rights.js";
export default {
	props:["h"],
	data() {
		return {
			isLoading:false,
			isShowAdd:false,
			isShowModify:false,
			isShowSeting:false,
			newRole:{
				roleName:"",
				roleDesc:""
			},
			modifyRole:{
				roleId:"",
				roleName:"",
				roleDesc:""
			},
			settingRoleId:0,
			allRights:[],
			roleRule:roleRules,
			roles:[],
		}
	},
	methods:{
		addRuleCallback(){
			this.$refs.addRole.validate(async (flag)=>{
				if(flag){
					let result = await addNewRole(this.newRole);
					if(!result) return;
					this.isShowAdd = false;
					this.$notify.success(`角色"${result.roleName}" : 添加成功`);
					this.loadAllRoles();
				}
			})
		},
		async showModifyModel(id){
			let result = await getRole(id);
			if(!result) return;
			this.modifyRole = result;
			this.isShowModify = true;
		},
		formatterCheckKeys(rights){
			let keys = [];
			for (let item of rights) {
				if(item.children===undefined){
					keys.push(item.id);
				}else{
					let temp = this.formatterCheckKeys(item.children);
					keys = keys.concat(temp);
				}
			}
			return keys;
		},
		showSetingModel(row){
			this.settingRoleId = row.id;
			this.isShowSeting = true;
			// data仓库数据的更新 和 页面渲染完成 是分开的
			// data仓库数据更新时同步的
			// 和该数据关联的页面更新是异步的
			// console.log(this.$refs.settingRoleRef);
			this.$nextTick(()=>{
				// console.log(this.$refs.settingRoleRef);
				// console.log(row.children)
				let keys = this.formatterCheckKeys(row.children);
				// console.log(keys);
				// this.$refs.settingRoleRef.setCheckedNodes(row.children);
				this.$refs.settingRoleRef.setCheckedKeys(keys);
			})
		},
		modifyRuleCallback(){
			this.$refs.modifyRoleRef.validate(async (flag)=>{
				if(flag){
					let data = {
						roleName:this.modifyRole.roleName,
						roleDesc:this.modifyRole.roleDesc
					}
					let result = await modifyRole(this.modifyRole.roleId,data);
					if(!result) return;
					this.isShowModify = false;
					this.$notify.success(`角色修改成功`);
					this.loadAllRoles();
				}
			})
		},
		async deleteRole(id){
			await removeRole(id);
			this.loadAllRoles();
		},
		async settingRoleRights(){
			let allCheck = this.$refs.settingRoleRef.getCheckedKeys();
			let halfCheck = this.$refs.settingRoleRef.getHalfCheckedKeys();
			console.log(allCheck,halfCheck);
			let rids = allCheck.concat(halfCheck).toString();
			await settingRoleRights(this.settingRoleId,{
				rids:rids
			});
			this.loadAllRoles();
			this.isShowSeting = false;
		},
		removeRights(role,rightId){
			this.$confirm('确定要删除该权限吗, 是否继续?', '提示', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning'
			}).then(async () => {
				let result = await removeRoleRights(role.id,rightId);
				if(!result) return;
				// console.log(result);
				role.children = result;
				// this.loadAllRoles();
			}).catch(() => {
				this.$message({
					type: 'info',
					message: '已取消删除'
				});          
			});
		},
		async loadAllRights(){
			let rights = await getAllRights();
			if(!rights) return;
			this.allRights = rights;
		},
		async loadAllRoles(){
			this.isLoading = true;
			let roles = await getAllroles();
			if(!roles) return;
			this.roles = roles;
			this.isLoading = false;
		}
	},
	created(){
		this.loadAllRoles();
		this.loadAllRights();
	}
}
</script>
<style lang="less" scoped>
.box-tip{
	text-align: center;
	color: #cccccc;
}
.el-tag{
	margin:10px 0px
}
.tag-box{
	display: flex;
	flex-flow: row nowrap;
	align-items: center;
	border-bottom: 1px solid #dedede;
}
.tag-box.warp{
	flex-flow: row wrap;
}
.box{
	border-top: 1px solid #dedede;
	flex-grow: 1;
}
.tag-box .tag-box:last-child{
	border-bottom: none;
}
.tag-box .box{
	margin-left: 40px;
	border: none;
}
.tag-box:last-child .box{
	border-bottom: none;
}
.tip{
	margin-right: 10px;
}
.el-tree{
	display: flex;
	flex-flow: row nowrap;
}
.el-tree::v-deep .el-tree-node{
	flex-grow: 1;
	flex-shrink: 0;
}
</style>